import { shallowMount, mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';

const localVue = createLocalVue();
localVue.use(Vuex);

class ComponentTestHelper {
  constructor() {
    this.localVue = localVue;
  }

  // 创建模拟Store
  createMockStore(stateOverrides = {}) {
    return new Vuex.Store({
      modules: {
        auth: {
          namespaced: true,
          state: {
            isAuthenticated: false,
            userInfo: null,
            token: '',
            ...stateOverrides.auth
          },
          getters: {
            isLoggedIn: state => state.isAuthenticated && !!state.token,
            points: state => state.userInfo?.points || 0
          },
          mutations: {
            SET_AUTH: (state, payload) => {
              state.isAuthenticated = payload.isAuthenticated;
              state.userInfo = payload.userInfo;
              state.token = payload.token;
            },
            CLEAR_AUTH: (state) => {
              state.isAuthenticated = false;
              state.userInfo = null;
              state.token = '';
            }
          },
          actions: {
            initAuth: jest.fn(),
            login: jest.fn(),
            logout: jest.fn()
          }
        }
      }
    });
  }

  // 浅渲染组件
  shallowMountComponent(component, options = {}) {
    const store = options.store || this.createMockStore();
    
    return shallowMount(component, {
      localVue: this.localVue,
      store,
      mocks: {
        $store: store,
        ...options.mocks
      },
      propsData: options.props || {},
      ...options
    });
  }

  // 完整渲染组件
  mountComponent(component, options = {}) {
    const store = options.store || this.createMockStore();
    
    return mount(component, {
      localVue: this.localVue,
      store,
      mocks: {
        $store: store,
        ...options.mocks
      },
      propsData: options.props || {},
      ...options
    });
  }

  // 测试组件数据更新
  async testDataUpdate(wrapper, newData) {
    wrapper.setData(newData);
    await wrapper.vm.$nextTick();
    return wrapper;
  }

  // 测试组件方法调用
  async testMethodCall(wrapper, methodName, ...args) {
    const result = await wrapper.vm[methodName](...args);
    await wrapper.vm.$nextTick();
    return result;
  }

  // 测试组件事件触发
  async testEventTrigger(wrapper, selector, eventName = 'click') {
    const element = wrapper.find(selector);
    expect(element.exists()).toBe(true);
    
    await element.trigger(eventName);
    await wrapper.vm.$nextTick();
    
    return element;
  }

  // 测试组件计算属性
  testComputedProperty(wrapper, propertyName, expectedValue) {
    expect(wrapper.vm[propertyName]).toEqual(expectedValue);
  }

  // 测试组件生命周期
  async testLifecycleHook(component, hookName, options = {}) {
    const spy = jest.spyOn(component.methods || {}, hookName);
    const wrapper = this.mountComponent(component, options);
    
    expect(spy).toHaveBeenCalled();
    spy.mockRestore();
    
    return wrapper;
  }

  // 模拟API调用
  mockApiCall(endpoint, response, shouldFail = false) {
    global.uni.request.mockImplementation((options) => {
      if (options.url.includes(endpoint)) {
        if (shouldFail) {
          return Promise.reject(new Error('API调用失败'));
        }
        return Promise.resolve({
          statusCode: 200,
          data: response
        });
      }
      return Promise.resolve({
        statusCode: 200,
        data: { success: true, data: {} }
      });
    });
  }

  // 测试错误处理
  async testErrorHandling(wrapper, errorTrigger) {
    const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
    
    try {
      await errorTrigger();
    } catch (error) {
      // 预期的错误
    }
    
    await wrapper.vm.$nextTick();
    consoleSpy.mockRestore();
    
    return wrapper;
  }

  // 测试加载状态
  async testLoadingState(wrapper, asyncOperation) {
    // 检查初始状态
    expect(wrapper.vm.loading || wrapper.vm.isLoading).toBeFalsy();
    
    // 触发异步操作
    const promise = asyncOperation();
    await wrapper.vm.$nextTick();
    
    // 检查加载状态
    expect(wrapper.vm.loading || wrapper.vm.isLoading).toBeTruthy();
    
    // 等待操作完成
    await promise;
    await wrapper.vm.$nextTick();
    
    // 检查完成状态
    expect(wrapper.vm.loading || wrapper.vm.isLoading).toBeFalsy();
    
    return wrapper;
  }

  // 测试权限控制
  testPermissionControl(wrapper, userRole, expectedBehavior) {
    // 设置用户角色
    wrapper.vm.$store.state.auth.userInfo = {
      ...wrapper.vm.$store.state.auth.userInfo,
      role: userRole
    };
    
    // 触发重新计算
    wrapper.vm.$forceUpdate();
    
    // 验证行为
    expectedBehavior(wrapper);
  }
}

export default ComponentTestHelper;